package cn.com.nes.site.service.system.company.impl;

import cn.com.nes.common.exception.BusinessException;
import cn.com.nes.common.exception.IllegalBusinessException;
import cn.com.nes.common.util.tree.TreeBuilder;
import cn.com.nes.mybatis.agent.system.entity.Company;
import cn.com.nes.mybatis.agent.system.entity.Department;
import cn.com.nes.mybatis.agent.system.mapper.DepartmentMapper;
import cn.com.nes.site.entity.em.DeleteEnum;
import cn.com.nes.site.entity.vo.system.DepartmentDeleteVO;
import cn.com.nes.site.entity.vo.system.DepartmentSaveVO;
import cn.com.nes.site.entity.vo.system.DepartmentTreeNodeVO;
import cn.com.nes.site.service.system.company.BusinessCompanyService;
import cn.com.nes.site.service.system.company.DepartmentService;
import cn.com.nes.site.service.system.company.dto.CompanyTreeNodeDTO;
import cn.com.nes.site.service.system.company.dto.DepartmentTreeNodeDTO;
import cn.com.nes.site.service.system.user.SystemUserService;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;

/**
 * 部门业务逻辑层
 */
@Slf4j
@Service
public class DepartmentServiceImpl extends ServiceImpl<DepartmentMapper, Department> implements DepartmentService {

    @Resource
    // @Lazy // 解决循环依赖问题
    BusinessCompanyService businessCompanyService;

    @Resource
    @Lazy
    SystemUserService systemUserService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Department saveDepartment(DepartmentSaveVO vo) throws Exception {
        Department department;

        Department sameNameDepartment = this.getDepartment(vo.getParentId(), vo.getDepartmentName());
        if (ObjectUtil.isNotNull(sameNameDepartment)) {
            throw new BusinessException("已存在相同名称的部门");
        }

        if (StrUtil.isEmpty(vo.getDepartmentId())) {
            department = new Department();
            department.setDepartmentName(vo.getDepartmentName());
            department.setDepartmentId(generateDepartmentId(vo.getParentId()));
            department.setCompanyId(vo.getParentId());
            department.setCompanyName(vo.getParentName());
            department.setDeleted(0);
            department.setGmtCreate(vo.getOperateDate());
            department.setGmtCreateId(131L);

            boolean isCompany = vo.getParentType().equals(0);
            if (isCompany) {
                department.setBelongCompanyId(vo.getParentId());
            } else {
                Department parentDepartment = this.getDepartment(vo.getParentId());
                department.setBelongCompanyId(parentDepartment.getBelongCompanyId());
            }
        } else {
            department = this.getDepartment(vo.getDepartmentId());
            department.setDepartmentName(vo.getDepartmentName());
            department.setGmtModified(vo.getOperateDate());
            department.setGmtModifiedId(vo.getOperateUserId());
        }

        this.saveOrUpdate(department);
        return department;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteDepartment(DepartmentDeleteVO vo) throws Exception {
        Department needsDeleteDepartment = this.getDepartment(vo.getDepartmentId());
        if (ObjectUtil.isNull(needsDeleteDepartment)) {
            throw new IllegalBusinessException("部门不存在");
        }

        if (ObjectUtil.isNull(vo.getDeletedUsers()) || !vo.getDeletedUsers()) {
            boolean hasChildDepartment = hasChildDepartmnet(vo.getDepartmentId());
            if (hasChildDepartment) {
                throw new BusinessException("存在子部门，不能删除");
            }

            boolean hasUsers = systemUserService.hasUsers(vo.getDepartmentId());
            if (hasUsers) {
                throw new BusinessException("当前部门存在用户");
            }
        }

        if (ObjectUtil.isNotNull(vo.getDeletedUsers()) && vo.getDeletedUsers()) {
            systemUserService.removeUserFormDepartment(vo.getDepartmentId(), vo.getOperateUserId(), vo.getOperateDate());
        }

        needsDeleteDepartment.setDeleted(1);
        needsDeleteDepartment.setGmtModified(vo.getOperateDate());
        needsDeleteDepartment.setGmtModifiedId(vo.getOperateUserId());
        this.saveOrUpdate(needsDeleteDepartment);
    }

    private boolean hasChildDepartmnet(String departmentId) throws Exception {
        List<Department> childDepartmnets = this.hasNextLevel(departmentId);
        if (CollUtil.isNotEmpty(childDepartmnets)) {
            return true;
        }
        return false;
    }

    /**
     * 生成部门ID
     * @param companyId 公司ID
     * @return
     */
    public String generateDepartmentId(String companyId) throws Exception {
        String lastChildDepartmentId = this.getLastDepartmentId(companyId);
        String newDepartmentId = "";
        if (StrUtil.isNotEmpty(lastChildDepartmentId)) {
            int nextDepartmentId = Integer.parseInt(lastChildDepartmentId) + 1;
            if (nextDepartmentId > 999) {
                newDepartmentId = "";
            } else {
                newDepartmentId = String.format("%03d", nextDepartmentId);
            }
        } else {
            newDepartmentId = "001";
        }
        if (newDepartmentId != null && !"".equals(newDepartmentId)) {
            newDepartmentId = companyId + "D" + newDepartmentId;
        }
        log.debug("创建部门 -> 数据库中查询到的部门ID[{}]，生成部门ID[{}]", lastChildDepartmentId, newDepartmentId);
        return newDepartmentId;
    }

    @Override
    public List<DepartmentTreeNodeDTO> getDepartmentTreeNode(DepartmentTreeNodeVO vo) throws Exception {
        List<DepartmentTreeNodeDTO> departmentList = this.baseMapper.getTreeNodeList(vo);
        Company company = businessCompanyService.getCompany(vo.getCompanyId());
        departmentList.add(0, new DepartmentTreeNodeDTO(company.getCompanyid(), company.getCompanyname(), null, 1));
        return new TreeBuilder<DepartmentTreeNodeDTO>().buildTree(departmentList);
    }

    @Override
    public List<CompanyTreeNodeDTO> getCompanyTreeNodeList(List<String> companyIds) throws Exception {
        return this.baseMapper.getCompanyTreeNodeList(companyIds);
    }

    @Override
    public Department getDepartmentForCompany(String companyId, String departmentName) throws Exception {
        return this.baseMapper.getDepartmentInCompany(companyId, departmentName);
    }

    public Department getDepartment(String parentId, String departmentName) throws Exception {
        return this.baseMapper.getDepartmentInCompany(parentId, departmentName);
    }

    @Override
    public Department getDepartment(String departmentId) throws Exception {
        Department department = this.baseMapper.getDepartmentUnDelete(departmentId);
        if (ObjectUtil.isNull(department)) {
            throw new IllegalBusinessException("部门不存在！");
        }
        return department;
    }

    @Override
    public List<Department> getDepartment(List<String> departmentId) throws Exception {
        if (CollUtil.isEmpty(departmentId)) {
            return Collections.emptyList();
        }
        QueryWrapper<Department> wrapper = new QueryWrapper<>();
        wrapper.eq("sfsc", DeleteEnum._0.getKey());
        wrapper.in("departmentId", departmentId);
        return this.list(wrapper);
    }

    @Override
    public List<Department> hasNextLevel(String departmentId) throws Exception {
        return this.baseMapper.getChildDepartments(departmentId);
    }

    @Override
    public String getLastDepartmentId(String companyId) throws Exception {
        return this.baseMapper.getLastChildDepartmentId(companyId);
    }

    @Override
    public Boolean departmentHasUsers(String departmentId) throws Exception {
        return systemUserService.hasUsers(departmentId);
    }


}
